home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / mg2a_src.zip / BUFFER.C < prev    next >
C/C++ Source or Header  |  1988-08-23  |  15KB  |  584 lines

  1. /*
  2.  *        Buffer handling.
  3.  */
  4. #include    "def.h"
  5. #include    "kbd.h"            /* needed for modes */
  6.  
  7. static RSIZE    itor();
  8.  
  9. /*
  10.  * Attach a buffer to a window. The values of dot and mark come
  11.  * from the buffer if the use count is 0. Otherwise, they come
  12.  * from some other window.  *scratch* is the default alternate
  13.  * buffer.
  14.  */
  15. /*ARGSUSED*/
  16. usebuffer(f, n)
  17. {
  18.     register BUFFER *bp;
  19.     register int    s;
  20.     char        bufn[NBUFN];
  21.  
  22.     /* Get buffer to use from user */
  23.     if ((curbp->b_altb == NULL)
  24.         && ((curbp->b_altb = bfind("*scratch*", TRUE)) == NULL))
  25.         s=eread("Switch to buffer: ", bufn, NBUFN, EFNEW|EFBUF);
  26.     else
  27.         s=eread("Switch to buffer: (default %s) ", bufn, NBUFN,
  28.              EFNEW|EFBUF, curbp->b_altb->b_bname);
  29.  
  30.     if (s == ABORT) return s;
  31.     if (s == FALSE && curbp->b_altb != NULL) bp = curbp->b_altb ;
  32.     else if ((bp=bfind(bufn, TRUE)) == NULL) return FALSE;
  33.  
  34.     /* and put it in current window */
  35.     curbp = bp;
  36.     return showbuffer(bp, curwp, WFFORCE|WFHARD);
  37. }
  38.  
  39. /*
  40.  * pop to buffer asked for by the user.
  41.  */
  42. /*ARGSUSED*/
  43. poptobuffer(f, n)
  44. {
  45.     register BUFFER *bp;
  46.     register WINDOW *wp;
  47.     register int    s;
  48.     char        bufn[NBUFN];
  49.     WINDOW    *popbuf();
  50.  
  51.     /* Get buffer to use from user */
  52.     if ((curbp->b_altb == NULL)
  53.         && ((curbp->b_altb = bfind("*scratch*", TRUE)) == NULL))
  54.         s=eread("Switch to buffer in other window: ", bufn, NBUFN,
  55.             EFNEW|EFBUF);
  56.     else
  57.         s=eread("Switch to buffer in other window: (default %s) ",
  58.              bufn, NBUFN, EFNEW|EFBUF, curbp->b_altb->b_bname);
  59.     if (s == ABORT) return s;
  60.     if (s == FALSE && curbp->b_altb != NULL) bp = curbp->b_altb ;
  61.     else if ((bp=bfind(bufn, TRUE)) == NULL) return FALSE;
  62.  
  63.     /* and put it in a new window */
  64.     if ((wp = popbuf(bp)) == NULL) return FALSE;
  65.     curbp = bp;
  66.     curwp = wp;
  67.     return TRUE;
  68. }
  69.  
  70. /*
  71.  * Dispose of a buffer, by name.
  72.  * Ask for the name. Look it up (don't get too
  73.  * upset if it isn't there at all!). Clear the buffer (ask
  74.  * if the buffer has been changed). Then free the header
  75.  * line and the buffer header. Bound to "C-X K".
  76.  */
  77. /*ARGSUSED*/
  78. killbuffer(f, n)
  79. {
  80.     register BUFFER *bp;
  81.     register BUFFER *bp1;
  82.     register BUFFER *bp2;
  83.     WINDOW        *wp;
  84.     register int    s;
  85.     char        bufn[NBUFN];
  86.  
  87.     if ((s=eread("Kill buffer: (default %s) ", bufn, NBUFN, EFNEW|EFBUF,
  88.             curbp->b_bname)) == ABORT) return (s);
  89.     else if (s == FALSE) bp = curbp;
  90.     else if ((bp=bfind(bufn, FALSE)) == NULL) return FALSE;
  91.  
  92.     /* find some other buffer to display. try the alternate buffer,
  93.      * then the first different buffer in the buffer list.    if
  94.      * there's only one buffer, create buffer *scratch* and make
  95.      * it the alternate buffer.  return if *scratch* is only buffer
  96.      */
  97.     if ((bp1 = bp->b_altb) == NULL) {
  98.         bp1 = (bp == bheadp) ? bp->b_bufp : bheadp;
  99.         if (bp1 == NULL) {
  100.             /* only one buffer. see if it's *scratch* */
  101.             if (bp == bfind("*scratch*",FALSE))
  102.                 return FALSE;
  103.             /* create *scratch* for alternate buffer */
  104.             if ((bp1 = bfind("*scratch*",TRUE)) == NULL)
  105.                 return FALSE;
  106.         }
  107.     }
  108.     if (bclear(bp) != TRUE) return TRUE;
  109.     for (wp = wheadp; bp->b_nwnd > 0; wp = wp->w_wndp) {
  110.         if (wp->w_bufp == bp) {
  111.         bp2 = bp1->b_altb;        /* save alternate buffer */
  112.         if(showbuffer(bp1, wp, WFMODE|WFFORCE|WFHARD) != NULL)
  113.             bp1->b_altb = bp2;
  114.         else    bp1 = bp2;
  115.         }
  116.     }
  117.     if (bp == curbp) curbp = bp1;
  118.     free((char *) bp->b_linep);        /* Release header line. */
  119.     bp2 = NULL;                /* Find the header.    */
  120.     bp1 = bheadp;
  121.     while (bp1 != bp) {
  122.         if (bp1->b_altb == bp)
  123.             bp1->b_altb = (bp->b_altb == bp1) ? NULL : bp->b_altb;
  124.         bp2 = bp1;
  125.         bp1 = bp1->b_bufp;
  126.     }
  127.     bp1 = bp1->b_bufp;            /* Next one in chain.    */
  128.     if (bp2 == NULL)            /* Unlink it.        */
  129.         bheadp = bp1;
  130.     else
  131.         bp2->b_bufp = bp1;
  132.     while (bp1 != NULL) {            /* Finish with altb's    */
  133.         if (bp1->b_altb == bp)
  134.             bp1->b_altb = (bp->b_altb == bp1) ? NULL : bp->b_altb;
  135.         bp1 = bp1->b_bufp;
  136.     }
  137.     free(bp->b_bname);            /* Release name block    */
  138.     free((char *) bp);            /* Release buffer block */
  139.     return TRUE;
  140. }
  141.  
  142. /*
  143.  * Save some buffers - just call anycb with the arg flag.
  144.  */
  145. /*ARGSUSED*/
  146. savebuffers(f, n)
  147. {
  148.     if (anycb(f) == ABORT) return ABORT;
  149.     return TRUE;
  150. }
  151.  
  152. /*
  153.  * Display the buffer list. This is done
  154.  * in two parts. The "makelist" routine figures out
  155.  * the text, and puts it in a buffer. "popbuf"
  156.  * then pops the data onto the screen. Bound to
  157.  * "C-X C-B".
  158.  */
  159. /*ARGSUSED*/
  160. listbuffers(f, n)
  161. {
  162.     register BUFFER *bp;
  163.     register WINDOW *wp;
  164.     BUFFER        *makelist();
  165.     WINDOW        *popbuf();
  166.  
  167.     if ((bp=makelist()) == NULL || (wp=popbuf(bp)) == NULL)
  168.         return FALSE;
  169.     wp->w_dotp = bp->b_dotp;    /* fix up if window already on screen */
  170.     wp->w_doto = bp->b_doto;
  171.     return TRUE;
  172. }
  173.  
  174. /*
  175.  * This routine rebuilds the text for the
  176.  * list buffers command. Return TRUE if
  177.  * everything works. Return FALSE if there
  178.  * is an error (if there is no memory).
  179.  */
  180. BUFFER *
  181. makelist() {
  182.     register char    *cp1;
  183.     register char    *cp2;
  184.     register int    c;
  185.     register BUFFER *bp;
  186.     LINE        *lp;
  187.     register RSIZE    nbytes;
  188.     BUFFER        *blp;
  189.     char        b[6+1];
  190.     char        line[128];
  191.  
  192.     if ((blp = bfind("*Buffer List*", TRUE)) == NULL) return NULL;
  193.     if (bclear(blp) != TRUE) return NULL;
  194.     blp->b_flag &= ~BFCHG;            /* Blow away old.    */
  195.  
  196.     (VOID) strcpy(line, " MR Buffer");
  197.     cp1 = line + 10;
  198.     while(cp1 < line + 4 + NBUFN + 1) *cp1++ = ' ';
  199.     (VOID) strcpy(cp1, "Size   File");
  200.     if (addline(blp, line) == FALSE) return NULL;
  201.     (VOID) strcpy(line, " -- ------");
  202.     cp1 = line + 10;
  203.     while(cp1 < line + 4 + NBUFN + 1) *cp1++ = ' ';
  204.     (VOID) strcpy(cp1, "----   ----");
  205.     if (addline(blp, line) == FALSE) return NULL;
  206.     bp = bheadp;                /* For all buffers    */
  207.     while (bp != NULL) {
  208.         cp1 = &line[0];            /* Start at left edge    */
  209.         *cp1++ = (bp == curbp) ? '.' : ' ';
  210.         *cp1++ = ((bp->b_flag&BFCHG) != 0) ? '*' : ' ';
  211.         *cp1++ = ' ';            /* Gap.            */
  212.         *cp1++ = ' ';
  213.         cp2 = &bp->b_bname[0];        /* Buffer name        */
  214.         while ((c = *cp2++) != 0)
  215.             *cp1++ = c;
  216.         while (cp1 < &line[4+NBUFN+1])
  217.             *cp1++ = ' ';
  218.         nbytes = 0;            /* Count bytes in buf.    */
  219.         if (bp != blp) {
  220.             lp = lforw(bp->b_linep);
  221.             while (lp != bp->b_linep) {
  222.                 nbytes += llength(lp)+1;
  223.                 lp = lforw(lp);
  224.             }
  225.             if(nbytes) nbytes--;    /* no bonus newline    */
  226.         }
  227.         (VOID) itor(b, 6, nbytes);    /* 6 digit buffer size. */
  228.         cp2 = &b[0];
  229.         while ((c = *cp2++) != 0)
  230.             *cp1++ = c;
  231.         *cp1++ = ' ';            /* Gap..            */
  232.         cp2 = &bp->b_fname[0];        /* File name        */
  233.         if (*cp2 != 0) {
  234.             while ((c = *cp2++) != 0) {
  235.                 if (cp1 < &line[128-1])
  236.                     *cp1++ = c;
  237.             }
  238.         }
  239.         *cp1 = 0;            /* Add to the buffer.    */
  240.         if (addline(blp, line) == FALSE)
  241.             return NULL;
  242.         bp = bp->b_bufp;
  243.     }
  244.     blp->b_dotp = lforw(blp->b_linep);    /* put dot at beginning of buffer */
  245.     blp->b_doto = 0;
  246.     return blp;                /* All done        */
  247. }
  248.  
  249. /*
  250.  * Used above.
  251.  */
  252. static RSIZE itor(buf, width, num)
  253. register char buf[]; register int width; register RSIZE num; {
  254.     register RSIZE r;
  255.  
  256.     if (num / 10 == 0) {
  257.         buf[0] = (num % 10) + '0';
  258.         for (r = 1; r < width; buf[r++] = ' ')
  259.             ;
  260.         buf[width] = '\0';
  261.         return 1;
  262.     } else {
  263.         buf[r = itor(buf, width, num / (RSIZE)10)] =
  264.                 (num % (RSIZE)10) + '0';
  265.         return r + 1;
  266.     }
  267.     /*NOTREACHED*/
  268. }
  269.  
  270. /*
  271.  * The argument "text" points to
  272.  * a string. Append this line to the
  273.  * buffer. Handcraft the EOL
  274.  * on the end. Return TRUE if it worked and
  275.  * FALSE if you ran out of room.
  276.  */
  277. addline(bp, text) register BUFFER *bp; char *text; {
  278.     register LINE    *lp;
  279.     register int    i;
  280.     register int    ntext;
  281.  
  282.     ntext = strlen(text);
  283.     if ((lp=lalloc(ntext)) == NULL)
  284.         return FALSE;
  285.     for (i=0; i<ntext; ++i)
  286.         lputc(lp, i, text[i]);
  287.     bp->b_linep->l_bp->l_fp = lp;        /* Hook onto the end    */
  288.     lp->l_bp = bp->b_linep->l_bp;
  289.     bp->b_linep->l_bp = lp;
  290.     lp->l_fp = bp->b_linep;
  291. #ifdef CANTHAPPEN
  292.     if (bp->b_dotp == bp->b_linep)        /* If "." is at the end    */
  293.         bp->b_dotp = lp;        /* move it to new line    */
  294.     if (bp->b_markp == bp->b_linep)        /* ditto for mark    */
  295.         bp->b_markp = lp;
  296. #endif
  297.     return TRUE;
  298. }
  299.  
  300. /*
  301.  * Look through the list of buffers, giving the user
  302.  * a chance to save them.  Return TRUE if there are
  303.  * any changed buffers afterwards. Buffers that don